package org.br.erp.base.creditrecord.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.br.erp.base.entity.Scmobject;
import org.br.erp.base.entity.Scmpartner;
import org.br.erp.base.entity.Scmpartnerbase;
import org.br.erp.base.service.IErpBaseService;
import org.br.erp.base.service.IScmobjectService;
import org.br.erp.base.service.IScmpartnerService;
import org.br.erp.base.service.IScmpartnerbaseService;
import org.br.erp.base.utils.ERPUtils;
import org.br.erp.base.creditcheckrule.entity.Scmcreditcheckrule;
import org.br.erp.base.creditcheckrule.entity.Scmcreditcheckruleitem;
import org.br.erp.base.creditcheckrule.service.IScmcreditcheckruleService;
import org.br.erp.base.creditcheckrule.service.IScmcreditcheckruleitemService;
import org.br.erp.base.creditrecord.entity.Scmcreditrecord;
import org.br.erp.base.creditrecord.entity.Scmcreditrecorditem;
import org.br.erp.base.creditrecord.entity.Scmcreditrecordattach;
import org.br.erp.base.creditrecord.mapper.ScmcreditrecorditemMapper;
import org.br.erp.base.creditrecord.mapper.ScmcreditrecordattachMapper;
import org.br.erp.base.creditrecord.mapper.ScmcreditrecordMapper;
import org.br.erp.base.creditrecord.service.IScmcreditrecordService;
import org.br.erp.base.creditrecord.service.IScmcreditrecorditemService;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 信用档案
 * @Author: jeecg-boot
 * @Date:   2024-03-26
 * @Version: V1.0
 */
@Service
public class ScmcreditrecordServiceImpl extends ServiceImpl<ScmcreditrecordMapper, Scmcreditrecord> implements IScmcreditrecordService {

	@Autowired
	private ScmcreditrecordMapper scmcreditrecordMapper;
	@Autowired
	private ScmcreditrecorditemMapper scmcreditrecorditemMapper;
	@Autowired
	private ScmcreditrecordattachMapper scmcreditrecordattachMapper;

	@Autowired
	private IScmpartnerService scmpartnerService;

	@Autowired
	private IScmpartnerbaseService scmpartnerbaseService;

	@Autowired
	private IScmcreditrecorditemService scmcreditrecorditemService;

	@Autowired
	private IScmcreditcheckruleService scmcreditcheckruleService;

	@Autowired
	private IScmcreditcheckruleitemService scmcreditcheckruleitemService;

	@Autowired
	private IScmobjectService scmobjectService;

	@Autowired
	private IErpBaseService erpBaseService;
	
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void saveMain(Scmcreditrecord scmcreditrecord, List<Scmcreditrecorditem> scmcreditrecorditemList,List<Scmcreditrecordattach> scmcreditrecordattachList) {
		scmcreditrecordMapper.insert(scmcreditrecord);
		if(scmcreditrecorditemList!=null && scmcreditrecorditemList.size()>0) {
			for(Scmcreditrecorditem entity:scmcreditrecorditemList) {
				//外键设置
				//判断当前客户是否已有其他定义
				String customerid = entity.getCustomerid();
				if(!ERPUtils.isNoneOrEmpty(customerid)){

					QueryWrapper<Scmcreditrecord> queryWrapper=new QueryWrapper<>();
					queryWrapper.exists("select 1 from scmcreditrecorditem where parentid = scmcreditrecord.id and scmcreditrecorditem.customerid = '"+customerid+"'");
					if(!ERPUtils.isNoneOrEmpty(scmcreditrecord.getFromdate())){
						queryWrapper.ge("fromdate",scmcreditrecord.getFromdate());
					}
					if(!ERPUtils.isNoneOrEmpty(scmcreditrecord.getEnddate())){
						queryWrapper.le("enddate",scmcreditrecord.getEnddate());
					}

					List<Scmcreditrecord> scmcreditrecords = scmcreditrecordMapper.selectList(queryWrapper);

					if(scmcreditrecords.size()>0){
						Scmpartner scmpartner = scmpartnerService.getById(customerid);
						throw new RuntimeException("分录"+scmpartner.getPartnername()+"已定义信用档案，不允许重复定义");
					}

				}

				entity.setParentid(scmcreditrecord.getId());
				scmcreditrecorditemMapper.insert(entity);
			}
		}
		if(scmcreditrecordattachList!=null && scmcreditrecordattachList.size()>0) {
			for(Scmcreditrecordattach entity:scmcreditrecordattachList) {
				//外键设置
				entity.setParentid(scmcreditrecord.getId());
				scmcreditrecordattachMapper.insert(entity);
			}
		}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void updateMain(Scmcreditrecord scmcreditrecord,List<Scmcreditrecorditem> scmcreditrecorditemList,List<Scmcreditrecordattach> scmcreditrecordattachList) {
		scmcreditrecordMapper.updateById(scmcreditrecord);
		
		//1.先删除子表数据
		scmcreditrecorditemMapper.deleteByMainId(scmcreditrecord.getId());
		scmcreditrecordattachMapper.deleteByMainId(scmcreditrecord.getId());
		
		//2.子表数据重新插入
		if(scmcreditrecorditemList!=null && scmcreditrecorditemList.size()>0) {
			for(Scmcreditrecorditem entity:scmcreditrecorditemList) {
				//外键设置
				entity.setParentid(scmcreditrecord.getId());
				scmcreditrecorditemMapper.insert(entity);
			}
		}
		if(scmcreditrecordattachList!=null && scmcreditrecordattachList.size()>0) {
			for(Scmcreditrecordattach entity:scmcreditrecordattachList) {
				//外键设置
				entity.setParentid(scmcreditrecord.getId());
				scmcreditrecordattachMapper.insert(entity);
			}
		}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void delMain(String id) {
		scmcreditrecorditemMapper.deleteByMainId(id);
		scmcreditrecordattachMapper.deleteByMainId(id);
		scmcreditrecordMapper.deleteById(id);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void delBatchMain(Collection<? extends Serializable> idList) {
		for(Serializable id:idList) {
			scmcreditrecorditemMapper.deleteByMainId(id.toString());
			scmcreditrecordattachMapper.deleteByMainId(id.toString());
			scmcreditrecordMapper.deleteById(id);
		}
	}

	/**
	 * 信用检查
	 * @param jsonObject
	 * @return
	 */
	public Map creditCheck(JSONObject jsonObject){

		HashMap res=new HashMap();

		if(!jsonObject.containsKey("customerid")){
			throw new RuntimeException("未传入客户信息，不能进行信用检查!");
		}
		String checkpoint = jsonObject.getString("checkpoint");
		String customerid = jsonObject.getString("customerid");

		//判断当前客户是否启用了信用管理
		List<Scmpartnerbase> scmpartnerbases = scmpartnerbaseService.selectByMainId(customerid);
		if(scmpartnerbases.size() == 0){
			return null;
		}
		Scmpartnerbase scmpartnerbase = scmpartnerbases.get(0);
		if(!(scmpartnerbase.getCreditflag()!=null && scmpartnerbase.getCreditflag().equalsIgnoreCase("Y"))){
			return null;
		}


		String objectid = jsonObject.getString("objectid");
		//根据客户去匹配对应的信用档案
		List<Scmcreditrecorditem> creditRecordItemByCustomerid = scmcreditrecorditemService.getCreditRecordItemByCustomerid(customerid);
		if(creditRecordItemByCustomerid.size() == 0){
			throw new RuntimeException("当前客户未定义信用档案");
		}
		//判断检查点是否定义的一致
		//todo 根据信用档案查询信用检查规则
		Scmcreditcheckrule scmcreditcheckrule = scmcreditcheckruleService.getById(creditRecordItemByCustomerid.get(0).getCheckruleid());

		if(scmcreditcheckrule==null){
			throw new RuntimeException("未定义信用检查规则");
		}

		//todo 2 信用检查规则分录信息，获取哪些单据参与检查
		List<Scmcreditcheckruleitem> scmcreditcheckruleitems = scmcreditcheckruleitemService.selectByMainId(scmcreditcheckrule.getId());
		List<Scmcreditcheckruleitem> collect = scmcreditcheckruleitems.stream().filter(item -> item.getObjectid().equalsIgnoreCase(objectid)).collect(Collectors.toList());
		//当前没有单据不参与信贷检查
		if(collect.size() == 0){
			return new HashMap<>();
		}

		Scmcreditcheckruleitem currentObjectCheckRuleItem = collect.get(0);


		String checkrulepoint = currentObjectCheckRuleItem.getCheckpoint();

		String creditValueCheckFlag = currentObjectCheckRuleItem.getCheckcreditvalueflag();

		if(!checkpoint.equalsIgnoreCase(checkrulepoint)){
			return new HashMap<>();
		}
		//todo 判断是否检查信用额度

		boolean issiglecreditcheckflag=false;

		String siglecreditcheckerrormeg="";

		boolean iscreditcheckflag= false;
		boolean iscreditdaycheckflag=false;
		boolean iscreditdayvaluecheckflag=false;
		//检查额度
		Scmobject scmobject = scmobjectService.getById(objectid);


		BigDecimal totalZYCreditValue = BigDecimal.ZERO;
		HashMap<String,HashMap> totalZYCreditValueMap=new HashMap<>();
		//去检查信用额度
		Scmcreditrecorditem scmcreditrecorditem = creditRecordItemByCustomerid.get(0);
		for (Scmcreditcheckruleitem scmcreditcheckruleitem : scmcreditcheckruleitems) {
			//额度更新，是否冲减额度
			String updatecreditvalueflag = scmcreditcheckruleitem.getUpdatecreditvalueflag();
			//额度检查
			String checkcreditvalueflag = scmcreditcheckruleitem.getCheckcreditvalueflag();
			//每单额度检查
			String checkcreditsigleflag = scmcreditcheckruleitem.getCheckcreditsigleflag();

			String checkcreditdayflag = scmcreditcheckruleitem.getCheckcreditdayflag();

			if(creditValueCheckFlag!=null && creditValueCheckFlag.equalsIgnoreCase("Y") && (updatecreditvalueflag!=null && updatecreditvalueflag.equalsIgnoreCase("Y"))) {
				//去遍历查询当前业务对象下的查询语句
				HashMap queryMap = new HashMap();
				queryMap.put("customerid", customerid);
				queryMap.put("querycode", scmobject.getObjectcode() + "creditquery");
				List<JSONObject> jsonObjects = erpBaseService.executeSqlWithParams(queryMap);
				if (jsonObjects != null && jsonObjects.size() > 0) {
					JSONObject curObject = jsonObjects.get(0);
					String creditdirection = scmcreditcheckruleitem.getCreditdirection();
					if(creditdirection!=null && creditdirection.equalsIgnoreCase("0")){
						totalZYCreditValue = totalZYCreditValue.add(ERPUtils.getBigDecimal(curObject.getString("lefttaxinvalue")));
					}else if(creditdirection!=null && creditdirection.equalsIgnoreCase("1")){
						totalZYCreditValue=totalZYCreditValue.subtract(ERPUtils.getBigDecimal(curObject.getString("lefttaxinvalue")));
					}
					HashMap hashMap = totalZYCreditValueMap.getOrDefault(creditdirection, new HashMap<>());
					hashMap.put(scmobject.getObjectname(), totalZYCreditValue);
					totalZYCreditValueMap.putIfAbsent(creditdirection, hashMap);
				}
			}
			if(checkcreditsigleflag!=null && checkcreditsigleflag.equalsIgnoreCase("Y") && scmcreditcheckruleitem.getObjectid().equalsIgnoreCase(objectid)){
				if(jsonObject.containsKey("currentvalue")){
					BigDecimal siglecreditvalue = scmcreditrecorditem.getSiglecreditvalue();
					//设置的限额
					if(siglecreditvalue==null){
						throw new RuntimeException("当前客户配置每单限额，但是未定义每单限额额度，请检查配置");
					}
					String currentvalue = jsonObject.getString("currentvalue");
					if(siglecreditvalue.compareTo(ERPUtils.getBigDecimal(currentvalue))<0){
						issiglecreditcheckflag=true;

						siglecreditcheckerrormeg="客户进行限额控制，整单限额:"+siglecreditvalue+",当前单据额度:"+currentvalue+"已超过限额";
						break;
					}
				}
			}
			if(checkcreditdayflag!=null && checkcreditdayflag.equalsIgnoreCase("Y")){
				//信贷超期天数
				BigDecimal creditday = scmcreditrecorditem.getCreditday();
				String dataAddDays = ERPUtils.getDataAddDays(ERPUtils.getDateString(ERPUtils.getLocalDate(),""), Integer.parseInt(creditday.multiply(BigDecimal.valueOf(-1)).toString()));
				//去遍历查询当前业务对象下的查询语句
				HashMap queryMap = new HashMap();
				queryMap.put("customerid", customerid);
				queryMap.put("querycode", scmobject.getObjectcode() + "creditquery");
				queryMap.put("billdate",dataAddDays);
				List<JSONObject> jsonObjects = erpBaseService.executeSqlWithParams(queryMap);
				if(jsonObjects!=null && jsonObjects.size()>0){
					iscreditdaycheckflag=true;
					break;
				}
			}
		}
		BigDecimal creditvalue = scmcreditrecorditem.getCreditvalue();
		//超标检查依据
			String overcreditcheckmethod = currentObjectCheckRuleItem.getOvercreditcheckmethod();

			if(overcreditcheckmethod!=null && overcreditcheckmethod.equalsIgnoreCase("0")){
				//单一超标就不通过
				String controlinfo = currentObjectCheckRuleItem.getControlinfo();
				BigDecimal totalValue = totalZYCreditValue.add(jsonObject.getBigDecimal("currentvalue"));
				if(totalValue.compareTo(creditvalue) >0){
					res.put(controlinfo,"当前客户占用额度："+totalZYCreditValue+";客户信贷额度共:"+creditvalue);
					return res;
				}
				if(iscreditdaycheckflag){
					res.put(controlinfo,"当前客户信贷期限不满足");
					return res;
				}
			}else if(overcreditcheckmethod!=null && overcreditcheckmethod.equalsIgnoreCase("1")){
				//同时控制，全部不合格才进行控制
			}
		return res;
	}
	
}
